import java.io.*;
import java.util.concurrent.ConcurrentLinkedQueue;

public class ConnectionReceiver extends Thread {
    // This class is a stand-alone thread set up to watch an object input stream.
    // It adds everything it receives to the public queue 'received', this is purely
    // to side-step the blocking issue with ObjectInputStream.readObject()
    
    public ConcurrentLinkedQueue<Pack> ReceivedData = new ConcurrentLinkedQueue<Pack>();
    public volatile boolean TerminateConnection = false;
    
    private ObjectInputStream input = null;
    private Logger log = null;
    
    public ConnectionReceiver(ObjectInputStream i, Logger l) {
        this.input = i;
        this.log = l;
    }
    
    public void run() {
        Pack p;
        while(!TerminateConnection) {
            p = receiveData();
            if(p != null) {
                ReceivedData.add(p);
                if(p.requestID == Pack.CLOSE_CONNECTION_ID) {
                    break;
                }
            }
        }
        
        close();
    }
    
    private Pack receiveData() {
    //  Receive data sent over stream
    //  Returns: true if receive successful, false if not
        Pack p = null;
        try {
            p = (Pack) input.readObject();
        } catch (EOFException eofe) {       // EOF exception - server closed connection without telling you!
            log.log(eofe);
            return new Pack(Pack.CLOSE_CONNECTION_ID, "Connection terminated by server unexpectantly.", "Error", "Error");
        } catch (IOException ioe) {
            log.log(ioe);
            return null;
        } catch (ClassNotFoundException cnfe) {
            log.log(cnfe);
            return null;
        }
        
        log.log("\n::Received Pack::\n" + p.toString());
        return p;
    }
    
    private void close() {
        try {
            input.close();
        } catch (Exception e) {
            log.log(e);
        }
    }
}
